package com.link.base.base.user.controller;

import com.alibaba.fastjson.JSONObject;
import com.link.base.base.user.model.User;
import com.link.base.base.user.model.RespDTO;
import com.link.base.base.user.model.ThirdLogin;
import com.link.base.base.user.model.ThirdLoginDTO;
import com.link.base.base.user.service.ThirdLoginService;
import com.link.core.cllog.LCLogger;
import com.link.core.basic.annotations.JsonParam;
import com.link.core.basic.controller.BasicController;
import com.link.core.basic.service.BasicService;
import com.link.core.basic.service.ServiceException;
import com.link.core.util.RedisUtil;
import com.link.core.util.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * QQ && 微信登录
 *
 * @author 曲元涛
 * @date 2019/03/29 17:19
 */
@Controller
@RequestMapping("/link/thirdParty")
public class ThirdLoginController extends BasicController<ThirdLogin> {

    @Resource
    private ThirdLoginService thirdPartyService;

    @Override
    public BasicService<ThirdLogin> getBasicService() throws Exception {
        return thirdPartyService;
    }

    private static final Long CORP_ID = 0L;

    /**
     * QQ\微信登录接口（无需密码，根据绑定信息登录）
     *
     * @author cuizhiyong
     * @param dto 接收platformType(平台类型),username(登录用户名),token(认证信息key)
     * @date 2019/4/3
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ResponseBody
    public RespDTO login(@RequestBody ThirdLoginDTO dto, HttpServletRequest request) {
        try {
            if (StringUtils.isBlank(dto.getToken())) {
                throw new ServiceException("USER-033");
            }
            if (StringUtils.isBlank(dto.getPlatformType())) {
                throw new ServiceException("USER-034");
            }
            if (StringUtils.isBlank(dto.getUsername())) {
                throw new ServiceException("USER-035");
            }
            if (StringUtils.isBlank(dto.getAppType())) {
                throw new ServiceException("USER-036");
            }
            return thirdPartyService.login(dto, request);
        } catch (Exception e) {
            LCLogger.withException(e);
            RespDTO respDTO = new RespDTO();
            respDTO.setError(e.getMessage());
            respDTO.setCode(-1);
            return respDTO;
        }
    }

    /**
     * 获取微信授权URL
     *
     * @author quyuantao
     * @date 2019/4/2 19:51
     */
    @RequestMapping(value = "/getWeChatAuthUrl", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> getWeChatAuthUrl(@RequestBody ThirdLoginDTO dto) {
        Map<String, Object> result = new HashMap<>(2);
        Map<String, Object> authRes = thirdPartyService.authControl("WX");
        if (!authRes.containsValue(true)) {
            result.put("success", false);
            result.put("result", authRes.get("WX"));
            return result;
        }
        String url = thirdPartyService.getWeChatAuthUrl(dto);
        if (!StringUtils.isNull(url)) {
            result.put("result", url);
            result.put("success", true);
        } else {
            result.put("success", false);
            result.put("result", "获取微信授权URL失败");
        }
        return result;
    }

    /**
     * QQ授权地址获取
     *
     * @author cuizhiyong
     * @date 2019/4/2 19:54
     * @param dto 接收appType
     */
    @RequestMapping("/getQQAuthUrl")
    @ResponseBody
    public Map<String, Object> getQQAuthUrl(@RequestBody ThirdLoginDTO dto) {
        Map<String, Object> result = new HashMap<>(2);
        result.put("success", false);
        if (StringUtils.isBlank(dto.getAppType())) {
            result.put("result", "请传入应用类型");
            return result;
        }
        if (StringUtils.isBlank(dto.getState())) {
            result.put("result", "请传入页面类型");
            return result;
        }
        Map<String, Object> authRes = thirdPartyService.authControl("QQ");
        if (!authRes.containsValue(true)) {
            result.put("result", authRes.get("QQ"));
            return result;
        }
        String url = thirdPartyService.getQQAuthUrl(dto);
        if (StringUtils.isNull(url)) {
            result.put("result", "获取QQ授权地址失败");
        } else {
            result.put("result", url);
            result.put("success", true);
        }
        return result;
    }

    /**
     * 个人中心QQ绑定重定向处理接口
     *
     * @author cuizhiyong
     * @date 2019/4/2 19:55
     * @param code  access code
     * @param state client状态
     */
    @GetMapping("/qqBindDo")
    public void bindDo(String code, String state, HttpServletResponse response) {
        String param = "";
        String page = "";
        try {
            String[] stateParam = state.split("_");
            if (stateParam.length < 2) {
                throw new ServiceException("未正确获取到appType");
            }
            JSONObject tokenObj = thirdPartyService.getQQAuthToken(code, state, false);
            param = "token=" + tokenObj.getString("access_token");
            param += "&refreshToken=" + tokenObj.getString("refresh_token");
            switch (stateParam[1]) {
                case "CRM":
                    page = RedisUtil.getProperty("systemLoginPage", CORP_ID.toString())
                            + "pages/crmhome/index.html?menu=/modules/crm/personal_center"
                            + "/personal_center_form/personal-center-form.vue,page=/modules/crm/"
                            + "personal_center/personal_center_form/personal-center-form.vue&";
                    break;
                case "DMS":
                    page = RedisUtil.getProperty("dmsDomain", CORP_ID.toString())
                            + "pages/dmshome/index.html?menu=personal-see-information&page=personal-see-information&";
                    break;
                case "STORE":
                    page = RedisUtil.getProperty("storeDomain", CORP_ID.toString())
                            + "pages/storehome/index.html"
                            + "?menu=personal-store-information&page=personal-store-information&";
                    break;
                default:
                    page = "";
            }
        } catch (Exception e) {
            try {
                param = "error=" + URLEncoder.encode(e.getMessage(), "UTF-8");
            } catch (UnsupportedEncodingException ex) {
                LCLogger.error().withMessage(ex.getMessage()).flush();
            }
            LCLogger.error().withMessage(e.getMessage()).flush();
        }
        try {
            response.sendRedirect(page + param);
        } catch (IOException e) {
            LCLogger.error().withMessage(e.getMessage()).flush();
        }
    }

    /**
     * 登录页QQ绑定重定向处理接口
     *
     * @author cuizhiyong
     * @date 2019/4/2 19:55
     * @param code  access code
     * @param state client状态
     */
    @GetMapping("/qqLoginDo")
    public void loginDo(String code, String state, HttpServletResponse response) {
        String param = thirdPartyService.getLoginRedirectParam(code, state, true);
        try {
            String[] stateParam = state.split("_");
            if (stateParam.length < 2) {
                throw new ServiceException("USER-037");
            }
            String mainPage = getMainPage(stateParam);
            response.sendRedirect(mainPage + "thirdlogin.html?" + param + "&platformType=QQ&appType=" + stateParam[1]);
        } catch (IOException e) {
            LCLogger.error().withMessage(e.getMessage()).flush();
        }
    }

    /**
     * web端扫码后绑定微信账号
     *
     * @author quyuantao
     * @date 2019/4/2 19:56
     */
    @GetMapping("/wxBindDo")
    public void wxBindDo(HttpServletRequest request, HttpServletResponse response) {
        String code = request.getParameter("code");
        String state = request.getParameter("state");
        String page = "";
        String param = "";
        try {
            String[] stateParam = state.split("_");
            if (stateParam.length < 2) {
                throw new ServiceException("USER-037");
            }
            param = "&code=" + code + "&state=" + state;
            switch (stateParam[1]) {
                case "CRM":
                    page = RedisUtil.getProperty("systemLoginPage", CORP_ID.toString())
                            + "pages/crmhome/index.html?menu=/modules/crm/personal_center"
                            + "/personal_center_form/personal-center-form.vue,page=/modules/crm/"
                            + "personal_center/personal_center_form/personal-center-form.vue";
                    break;
                case "DMS":
                    page = RedisUtil.getProperty("dmsDomain", CORP_ID.toString())
                            + "pages/dmshome/index.html?menu=personal-see-information&page=personal-see-information";
                    break;
                case "STORE":
                    page = RedisUtil.getProperty("storeDomain", CORP_ID.toString())
                            + "pages/storehome/index.html"
                            + "?menu=personal-store-information&page=personal-store-information";
                    break;
                default:
                    page = "";
            }
        } catch (Exception e) {
            try {
                param = "&error=" + URLEncoder.encode(e.getMessage(), "UTF-8");
            } catch (UnsupportedEncodingException e1) {
                LCLogger.error().withMessageKey("wxBindDo").withMessage(e1.getMessage()).flush();
            }
            LCLogger.error().withMessageKey("wxBindDo").withMessage(e.getMessage()).flush();
        }
        try {
            response.sendRedirect(page + param);
        } catch (IOException e) {
            LCLogger.error().withMessageKey("重定向到登录页失败").withMessage(e.getMessage()).flush();
        }
    }

    /**
     * web端扫码后，登录接口
     *
     * @author quyuantao
     * @date 2019/4/2 19:56
     */
    @GetMapping(value = "/wxLoginDo")
    public void wxLoginDo(HttpServletRequest request, HttpServletResponse response) {
        //获取微信code临时票据
        String code = request.getParameter("code");
        //随机字符串state
        String state = request.getParameter("state");
        String[] stateParam = state.split("_");
        String param = "";
        try {
            if (stateParam.length < 2) {
                throw new ServiceException("USER-037");
            }
            param = "token=" + thirdPartyService.getWXRandomToken(code, state, "CRM");
        } catch (Exception e) {
            try {
                param = "error=" + URLEncoder.encode(e.getMessage(), "UTF-8");
            } catch (UnsupportedEncodingException e1) {
                LCLogger.error().withMessageKey("wxLoginDo").withMessage(e.getMessage()).flush();
            }
            LCLogger.error().withMessageKey("wxLoginDo").withMessage(e.getMessage()).flush();
        }
        try {
            String mainPage = getMainPage(stateParam);
            response.sendRedirect(mainPage + "thirdlogin.html?" + param + "&platformType=WX&appType=" + stateParam[1]);
        } catch (IOException e) {
            LCLogger.error().withMessageKey("重定向第三方登录页失败").withMessage(e.getMessage()).flush();
        }
    }

    /**
     * 根据应用类型获取主域名
     *
     * @author quyuantao
     * @date 2019/4/22 17:12
     * @param stateParam state字符串数组
     */
    private String getMainPage(String[] stateParam) {
        String mainPage;
        switch (stateParam[1]) {
            case "CRM":
                mainPage = RedisUtil.getProperty("systemLoginPage", CORP_ID.toString());
                break;
            case "DMS":
                mainPage = RedisUtil.getProperty("dmsDomain", CORP_ID.toString());
                break;
            case "STORE":
                mainPage = RedisUtil.getProperty("storeDomain", CORP_ID.toString());
                break;
            default:
                mainPage = "";
        }
        return mainPage;
    }

    /**
     * 个人中心- QQ 微信绑定情况
     *
     * @author quyuantao
     * @date 2019/4/2 19:57
     * @param login 第三方登录Model类
     */
    @RequestMapping(value = "/thirdPartyBinding", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> thirdPartyBinding(@JsonParam ThirdLogin login) {
        Map<String, Object> result = new HashMap<>(4);
        try {
            result = thirdPartyService.thirdPartyBinding(login);
            result.put("success", true);
        } catch (Exception e) {
            LCLogger.withException(e.getMessage());
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 綁定微信（个人中心）
     *
     * @author quyuantao
     * @date 2019/4/2 19:57
     * @param dto 参数对象
     */
    @RequestMapping(value = "/bindWx", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> bindThirdParty(@RequestBody ThirdLoginDTO dto) {
        Map<String, Object> result = new HashMap<>(2);
        try {
            String state = dto.getState();
            String code = dto.getCode();
            String appType = dto.getAppType();
            JSONObject tokenObject = thirdPartyService.bindWx(state, code, appType);
            result.put("success", true);
            result.put("result", tokenObject);
        } catch (Exception e) {
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 绑定QQ（个人中心）
     *
     * @author cuizhiyong
     * @date 2019/4/2 19:57
     * @param dto 参数对象
     */
    @RequestMapping("/bindQQ")
    @ResponseBody
    public Map<String, Object> bindQQ(@RequestBody ThirdLoginDTO dto) {
        Map<String, Object> result = new HashMap<>(2);
        try {
            if (StringUtils.isBlank(dto.getAppType())) {
                throw new ServiceException("USER-036");
            }
            if (StringUtils.isBlank(dto.getToken())) {
                throw new ServiceException("USER-033");
            }
            JSONObject res = thirdPartyService.bindQQ(dto);
            result.put("success", true);
            result.put("result", res);
        } catch (ServiceException bse) {
            result.put("success", false);
            result.put("result", bse.getMessage());
        } catch (Exception e) {
            result.put("success", false);
            result.put("result", e.getMessage());
            LCLogger.error().withMessageKey("bindQQ").withMessage(e.getMessage()).flush();
        }
        return result;
    }

    /**
     * 解绑第三方账号
     *
     * @author quyuantao
     * @date 2019/4/2 19:58
     * @param dto 参数对象
     */
    @RequestMapping(value = "/unboundThirdParty")
    @ResponseBody
    public Map<String, Object> unboundThirdParty(@RequestBody ThirdLoginDTO dto) {
        Map<String, Object> result = new HashMap<>(2);
        result.put("success", false);
        try {
            String appType = dto.getAppType();
            String platformType = dto.getPlatformType();
            if (StringUtils.isBlank(appType)) {
                throw new ServiceException("USER-036");
            }
            if (StringUtils.isBlank(platformType)) {
                throw new ServiceException("USER-034");
            }
            Map<String, Object> authRes = thirdPartyService.authControl(platformType);
            if (!authRes.containsValue(true)) {
                result.put("result", authRes.get(platformType));
                return result;
            }
            thirdPartyService.unBoundThirdParty(appType, platformType);
            result.put("success", true);
            result.put("result", "解绑成功");
        } catch (Exception e) {
            result.put("result", e.getMessage());
            LCLogger.error().withMessageKey("unboundThirdParty").withMessage(e.getMessage()).flush();
        }
        return result;
    }

    /**
     * 获取当前微信\QQ已绑定账号
     *
     * @author cuizhiyong
     * @date 2019/4/2 19:58
     * @param dto 参数对象
     */
    @RequestMapping("/getLoginUser")
    @ResponseBody
    public Map<String, Object> getLoginUser(@RequestBody ThirdLoginDTO dto) {
        Map<String, Object> result = new HashMap<>(2);
        try {
            if (StringUtils.isBlank(dto.getAppType())) {
                throw new ServiceException("USER-036");
            }
            if (StringUtils.isBlank(dto.getToken())) {
                throw new ServiceException("USER-033");
            }
            if (StringUtils.isBlank(dto.getPlatformType())) {
                throw new ServiceException("USER-034");
            }
            List<User> list =
                    thirdPartyService.getUsersByUnionIdAndAppType(dto.getAppType(), dto.getToken(), dto.getPlatformType(), dto.isWxSecAuth());
            result.put("success", true);
            result.put("result", list);
        } catch (Exception e) {
            result.put("success", false);
            result.put("result", e.getMessage());
            LCLogger.error().withMessageKey("unboundThirdParty").withMessage(e.getMessage()).flush();
        }
        return result;
    }

    /**
     * 微信避免二次授权
     *
     * @author quyuantao
     * @date 2019/4/8 15:42
     * @param dto 参数对象
     */
    @RequestMapping(value = "/wxSecAuth")
    @ResponseBody
    public Map<String, Object> wxSecAuth(@RequestBody ThirdLoginDTO dto) {
        Map<String, Object> result = new HashMap<>(2);
        try {
            String unionId = dto.getUnionId();
            String openId = dto.getOpenId();
            String accessToken = dto.getAccessToken();
            String appType = dto.getAppType();
            if (StringUtils.isBlank(unionId)) {
                throw new ServiceException("USER-038");
            }
            if (StringUtils.isBlank(openId)) {
                throw new ServiceException("USER-039");
            }
            if (StringUtils.isBlank(accessToken)) {
                throw new ServiceException("USER-040");
            }
            if (StringUtils.isBlank(appType)) {
                throw new ServiceException("USER-036");
            }
            boolean refreshed = thirdPartyService.wxSecAuth(unionId, openId, accessToken, appType);
            result.put("success", true);
            result.put("result", refreshed);
        } catch (Exception e) {
            result.put("success", false);
            result.put("result", e.getMessage());
            LCLogger.error().withMessageKey("wxSecAuth").withMessage(e.getMessage()).flush();
        }
        return result;
    }

    /**
     * 移动端获取token字符串接口，缓存认证信息
     *
     * @author quyuantao
     * @date 2019/4/3 10:58
     * @param dto 参数对象 (code --- 临时票据 state --- 空 appType --- 应用类型)
     */
    @RequestMapping(value = "/getWXRandomToken")
    @ResponseBody
    public Map<String, Object> getWXRandomToken(@RequestBody ThirdLoginDTO dto) {
        Map<String, Object> result = new HashMap<>(2);
        try {
            String token = thirdPartyService.getWXRandomToken(dto.getCode(), dto.getState(), dto.getAppType());
            result.put("token", token);
            result.put("success", true);
        } catch (Exception e) {
            result.put("success", false);
            result.put("result", e.getMessage());
            LCLogger.error().withMessageKey("getWXRandomToken").withMessage(e.getMessage()).flush();
        }
        return result;
    }

    /**
     * Web && APP 查询 QQ、微信登录权限
     *
     * @author quyuantao
     * @date 2019/6/16 18:02
     */
    @RequestMapping(value = "/thirdPartyAuthing")
    @ResponseBody
    public Map<String, Object> thirdPartyAuthing() {
        Map<String, Object> authRes = thirdPartyService.authControl("QQ", "WX");
        if (!authRes.get("QQ").equals(true)) {
            authRes.put("QQ", false);
        }
        if (!authRes.get("WX").equals(true)) {
            authRes.put("WX", false);
        }
        authRes.put("success", true);
        return authRes;
    }
}
